package com.wxapp.pay.service.pay.alipay;

import com.wxapp.common.base.util.jackson.JacksonUtil;
import com.wxapp.common.core.filter.except.ThrowMyException;
import com.wxapp.common.util.check.CheckUtil;
import com.wxapp.common.util.feign.DynamicFeignUtil;
import com.wxapp.common.util.http.HttpRequestUtil;
import com.wxapp.pay.api.pojo.enums.listener.RedirectTypeEnum;
import com.wxapp.pay.api.pojo.pojo.vm.pay.PAliPayVm;
import com.wxapp.pay.api.pojo.pojo.vm.pay.PPayOrderVm;
import com.wxapp.pay.api.pojo.pojo.vm.pay.PPayVm;
import com.wxapp.pay.api.pojo.pojo.vm.payConfig.PAliPayConfigsVm;
import com.wxapp.pay.api.pojo.pojo.vo.order.QOrderInfoVo;
import com.wxapp.pay.api.pojo.pojo.vo.payLogs.QPayLogsAddVo;
import com.wxapp.pay.service.event.PayLogsEvent;
import com.wxapp.pay.service.service.PayConfigService;
import com.wxapp.pay.service.util.AliPaySignUtil;
import com.wxapp.pay.service.util.UrlUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;

import java.util.Map;

/**
 * @author lgl
 */
@Component
@Slf4j
@RequiredArgsConstructor
public class AppAliPay extends BaseAliPay {
    protected static final String payWay = "AppAliPay";
    private final ApplicationEventPublisher publisher;
    private final DynamicFeignUtil dynamicFeignUtil;
    private final PayConfigService payConfigService;

    @Override
    protected String getType() {
        return payWay;
    }

    @Override
    protected PAliPayVm getRequestVm(PAliPayConfigsVm config, QOrderInfoVo vo) throws ThrowMyException {
        PAliPayVm pAliPayVm = new PAliPayVm();
        pAliPayVm.setApp_id(config.getAppId()).setFormat(config.getFormat()).setCharset(config.getCharset())
                .setSign_type(config.getSignType()).setAlipay_sdk(config.getAlipaySdk())
                .setVersion(config.getVersion()).setMethod(config.getMethod());
        PPayOrderVm pPayOrderVm = new PPayOrderVm(vo.getQOrderVm().getCode(), vo.getQOrderVm().getPrice(), vo.getPayName(), config.getProductCode());
        pAliPayVm.setBiz_content(JacksonUtil.toJSONString(pPayOrderVm));
        pAliPayVm.setSign(AliPaySignUtil.getSign(config.getPrivateKey(), JacksonUtil.parseObject(pAliPayVm, Map.class)));
        return pAliPayVm;
    }

    @Override
    protected PPayVm<String> dealResponseVm(PAliPayConfigsVm config, PAliPayVm vm) throws ThrowMyException {
        Map<String,String> signMap = JacksonUtil.parseObject(vm, Map.class);
        signMap.put("sign", vm.getSign());
        return new PPayVm<>(200, "支付成功", "", UrlUtil.createLinkString(signMap, true));
    }

    @Override
    protected void publicEvent(QPayLogsAddVo vo, ApplicationEvent... event) {
        publisher.publishEvent(new PayLogsEvent(this, "", vo));
        if (CheckUtil.isNullArray(event)) {
            return;
        }
        for (ApplicationEvent e : event) {
            publisher.publishEvent(e);
        }
    }

    @Override
    protected Boolean checkResponse(PPayVm<String> vm, PAliPayVm vp) {
        return vm.getCode() == 200;
    }

    @Override
    protected Boolean redirect(QOrderInfoVo vo) {
        try {
            if (vo.getRequestType()== RedirectTypeEnum.HTTP_REQUEST){
                HttpRequestUtil.request(vo.getHttpRedirect());
            }else if (vo.getRequestType()== RedirectTypeEnum.FEIGN_REQUEST){
                dynamicFeignUtil.executeApi(vo.getFeignRedirect());
            }else {
                return false;
            }
            return true;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 从数据库中获取支付配置
     */
    @Override
    protected PAliPayConfigsVm getConfigs() throws ThrowMyException {
        var config = payConfigService.getConfigsByCode(payWay);
        if (CheckUtil.isNullMap(config.getData())) {
            throw new ThrowMyException("没有找到支付方式");
        }
        return new PAliPayConfigsVm(config.getData());
    }
}
